#模块名：page_base
#标记：董哥的web自动化神器,报名学习：13760453683
import time,autoit
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.select import Select

#web自动化的页面父类：以后每个页面类都从该类继承。
class PageBase(object):
    def __init__(self,driver,base_url):
        self.driver=driver
        self.base_url=base_url

    #通用UI操作：打开某url
    def open(self,pathUrl):#给：“/webzdh/zucea.html”
        self.driver.get(f"{self.base_url}{pathUrl}")

    #通用UI操作：定位元素
    def find_element(self,loc,isHightDisplay=False):
        by=loc[0]
        value=loc[1]
        ele=self.driver.find_element(by, value)
        if isHightDisplay:
            self.driver.execute_script("arguments[0].setAttribute('style','background: green; border: 2px solid red;color: red;')",ele)
        return ele

    def find_elements(self,loc):
        by = loc[0]
        value = loc[1]
        return self.driver.find_elements(by, value)

    #通用UI操作：点击某元素.也支持鼠标点击
    def click(self,loc,isHightDisplay=False,isMouseClick=False):
        ele=self.find_element(loc,isHightDisplay)
        if isMouseClick:
            ActionChains(self.driver).click(ele).perform()
        else:
            ele.click()

    #适合控件：文本框、密码框、多行文本框
    #通用UI操作：给某控件输入数据。也支持JS输入。
    def input(self,loc,data,isHightDisplay=False,isJsInput=False):
        ele=self.find_element(loc,isHightDisplay)
        if isJsInput:
            self.driver.execute_script("arguments[0].value=arguments[1]",ele,data)
        else:
            ele.send_keys(data)

    # 适合控件：文本框、密码框、多行文本框
    # 通用UI操作：清空某控件中的输入值。也支持JS清除、键盘清除
    def clear(self,loc,type=1):
        ele=self.find_element(loc)
        if type==1:
            ele.clear()
        elif type==2:
            self.driver.execute_script("arguments[0].value=''",ele)
        else:
            ele.send_keys(Keys.CONTROL,"a")
            ele.send_keys(Keys.BACKSPACE)

    #获取某控件的属性的值
    def getEleAttr(self,loc,attrName,isStrip=True):
        ele=self.find_element(loc)
        attrName=ele.get_attribute(attrName)
        if isStrip:
            attrName=attrName.strip()
        return attrName

    #获取某控件的文本内容
    def getEleText(self,loc,isStrip=True):
        ele=self.find_element(loc)
        text=ele.text
        if isStrip:
            text=text.strip()
        return text

    #判断某元素是否在当前页面中存在
    def isExists(self,loc):
        try:
            self.find_element(loc)
            return True
        except Exception:
            return False

    # 适合控件：单选按钮
    # 功能：选中某选项
    def radio_click(self,attrName,optionValue):
        ele=self.driver.find_element_by_css_selector(f"input[type='radio'][name='{attrName}'][value='{optionValue}']")
        ele.click()

    #适合控件：复选框
    #功能：全选
    def check_AllSelect(self,attrName):
        allOption = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOption:
            cusiStatus = x.is_selected()
            if not cusiStatus:
                x.click()

    # 适合控件：复选框
    # 功能：全不选
    def checkbox_AllNotSelect(self,attrName):
        allOption = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOption:
            cusiStatus = x.is_selected()
            if cusiStatus:
                x.click()

    # 适合控件：复选框
    # 功能：反选
    def checkbox_reverseSelect(self,attrName):
        allOption = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOption:
            x.click()

    # 适合控件：复选框
    # 功能：选中指定的N个选项。N>=0
    def checkbox_click(self,attrName,targetValues): #给：targetValues="dalanqiu,tizuqiu" ""
        allOption = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOption:
            AttrValue = x.get_attribute("value")
            cusiStatus = x.is_selected()
            if AttrValue in targetValues:
                if not cusiStatus:
                    x.click()
            else:
                if cusiStatus:
                    x.click()


    #适合控件：下拉列表
    #功能：选中某个选项。支持根据下标/value属性(默认)/文本内容来选中。
    def select_click(self,attrName,data,type=2):
        haha = Select(self.driver.find_element_by_css_selector(f"select[name='{attrName}']"))
        if type==1:
            haha.select_by_index(data)
        elif type==2:
            haha.select_by_value(data)
        else:
            haha.select_by_visible_text(data)


    #适合控件：日期类控件
    def input_riqi(self,loc,riqi,isJsInput=True,isReadonly=False,isHightDisplay=False):
        ele=self.find_element(loc,isHightDisplay)
        if isReadonly:
            self.driver.execute_script("arguments[0].removeAttribute('readonly')", ele)
        if isJsInput:
            self.driver.execute_script("arguments[0].value=arguments[1]",ele,riqi)
        else:
            ele.send_keys(riqi)


    #适合控件：文件框。支持上传N个文件/文件夹.N>=0。也支持autoIT库
    def uploadFilesOrDirs(self,loc,filePath,type=1):#给："C:/A/1.png,C:/A/2.png" "" "C:/A/1.png"
        if filePath=="" or filePath == None:
            return
        if type==1:
            ele = self.find_element(loc)
            newFilePath = filePath.replace(",", "\n")
            ele.send_keys(newFilePath)
        else:
            ele = self.find_element(loc)
            ActionChains(self.driver).click(ele).perform()
            time.sleep(2)

            newFilePath = ""
            a = filePath.split(",")
            for x in a:
                newFilePath += '"' + x + '" '
            newFilePath2 = newFilePath.replace("/", "\\")

            autoit.win_wait("打开", 10)
            autoit.control_send("打开", "Edit1", newFilePath2)
            autoit.control_click("打开", "Button1")

    # 处理JS三种弹出框
    # 获取三种JS弹出框的文本内容
    def getTextForJsTanCuKuan(self):
        return self.driver.switch_to.alert.text

    # 点击三种JS弹出框的“确定”按钮
    def acceptForJsTanCuKuan(self):
        self.driver.switch_to.alert.accept()

    # 点击三种JS弹出框的“取消”按钮
    def dismissForJsTanCuKuan(self):
        self.driver.switch_to.alert.dismiss()

    # 为JS的prompt弹出框输入文本
    def inputJsTanCuKuan(self, data):
        self.driver.switch_to.alert.send_keys(data)

    # iframe框架相关处理
    # 切换到某iframe
    def switchTo_iframe(self, data, type=2):
        if type==1:#WebElement对,此时data:loc
            self.driver.switch_to.frame(self.find_element(data))
        else:#name属性或id属性、或int类型的下标
            self.driver.switch_to.frame(data)


    # 切换到主iframe
    def switch_defaultIframe(self):
        self.driver.switch_to.default_content()

    # 鼠标操作的相关处理
    # 函数功能：鼠标单击某元素loc
    def mouse_click(self, loc, isHightDisplay=False):
        ele = self.find_element(loc, isHightDisplay)
        ActionChains(self.driver).click(ele).perform()

    # 函数功能：鼠标双击某元素loc
    def mouse_dbclick(self, loc, isHightDisplay=False):
        ele = self.find_element(loc, isHightDisplay)
        ActionChains(self.driver).double_click(ele).perform()

    # 函数功能：鼠标悬停在某元素loc
    def mouse_moveToEle(self, loc, isHightDisplay=False):
        ele = self.find_element(loc, isHightDisplay)
        ActionChains(self.driver).move_to_element(ele).perform()

    # 函数功能：滑动垂直滚动条到最底部
    def scrollToFloor(self):
        js1 = "window.scrollTo(0,10000)"
        self.driver.execute_script(js1)

    # 网页截图
    def savePng1(self, filePath):#给："C:/A/haha.png"
        self.driver.get_screenshot_as_file(filePath)

    def savePng2(self, fileName):#给："登录"
        self.driver.get_screenshot_as_file("./screen/" + fileName + ".png")

    def savePng3(self, serviceName, key):
        fileName = serviceName + "_" + key + "_" + time.strftime("%Y%m%d%H%M%S")#"登录_K001_20250813164203"
        self.driver.get_screenshot_as_file("./screen/" + fileName + ".png")
        return fileName  # "登录_K001_20250605100314"

    #功能：切换windows。支持按下标/目标窗口的窗口标题/目标窗口的窗口url来切换。
    def swithTo_window(self,data=-1,type=1):
        if type==1:#按窗口的下标来切。从0开始
            self.driver.switch_to.window(self.driver.window_handles[data])
        elif type==2:#按窗口的目标标题来切换,data:给目标窗口的窗口标题（支持模拟匹配）
            morenHandler=self.driver.current_window_handle #刚开始切换之前的那个窗口的句柄
            flag=True #默认：没有目标窗口，即默认是找不到目标窗口
            allHandler = self.driver.window_handles
            for x in allHandler:  # x分别是每个窗口的窗口句柄
                self.driver.switch_to.window(x)
                if data in self.driver.title:
                    flag=False #找到了目标窗口
                    break
            if flag:
                self.driver.switch_to.window(morenHandler)
        else:#按窗口的目标url来切换,data：给目标窗口的窗口url（支持模糊匹配）
            morenHandler = self.driver.current_window_handle  # 刚开始切换之前的那个窗口的句柄
            flag = True  # 默认：没有目标窗口，即默认是找不到目标窗口
            allHandler = self.driver.window_handles
            for x in allHandler:  # x分别是每个窗口的窗口句柄
                self.driver.switch_to.window(x)
                if data in self.driver.current_url:
                    flag = False  # 找到了目标窗口
                    break
            if flag:
                self.driver.switch_to.window(morenHandler)








